package com.atguigu.crowd.controller;

import atguigu.crowd.constant.CrowdConstant;
import atguigu.crowd.util.ResultEntity;
import com.atguigu.crowd.api.MySQLRemoteService;
import com.atguigu.crowd.api.RedisRemoteService;
import com.atguigu.crowd.config.PO.MemberPO;
import com.atguigu.crowd.config.VO.MemberLoginVO;
import com.atguigu.crowd.config.VO.MemberVO;
import com.atguigu.crowd.config.VO.PortalTypeVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.Objects;


@Controller
@Slf4j
public class PortalHandler {

    @Autowired
    private RedisRemoteService redisRemoteService;

    @Autowired
    private MySQLRemoteService mySQLRemoteService;

    // 获取验证码
    @PostMapping("/auth/member/send/short/message.json")
    @ResponseBody   // 返回json
    public ResultEntity<String> sendMessage(@RequestParam("phoneNum") String phoneNum) {
//        try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }

        String code = String.valueOf(Math.round((Math.random() + 1) * 1000));
        // 验证码为：REGISTER_CODE_phoneNum,并设置过期时间为900s  15分钟
        redisRemoteService.setRedisKeyValueRemoteWithTimeOut(CrowdConstant.ATTR_REGISTER_CODE + phoneNum, code, 900L);
        return ResultEntity.successWithoutData();
    }

    @PostMapping("/auth/welcome/member/register")
    public String saveRegisterMessage(MemberVO memberVO, ModelMap modelMap) {
        // 1、获取用户输入的手机号
        String phoneNum = memberVO.getPhoneNum();
        String register_key = CrowdConstant.ATTR_REGISTER_CODE + phoneNum;

        // 账号被使用
        String loginacct = memberVO.getLoginacct();
        ResultEntity<MemberPO> remote = mySQLRemoteService.getMemberPOByLoginAcctRemote(loginacct);
        if (remote.getData() != null) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_LOGIN_ACCT_ALREADY_IN_USE);
            return "member-reg";
        }

        // 2、拼Redis中存储的验证码
        ResultEntity<String> value = redisRemoteService.getRedisStringValueByKeyRemote(register_key);

        // 手机号重复获取验证码
        String redis_code = value.getData();
        if (Objects.equals(redis_code, register_key)) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_TELEPHONE_REPEAT);
            return "member-reg";
        }

        // 检查查询操作是否有效
        String result = value.getResult();
        if (ResultEntity.FAILED.equals(result)) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, value.getMessage());

            return "member-reg";
        }

        // 不等于空，就代表value有值
        if (redis_code != null) {
            String code = memberVO.getCode();

            // 验证码不相等
            if (!Objects.equals(code, redis_code)) {
                modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_CODE_INVALID);

                return "member-reg";
            }

            // 如果验证码一致,将Redis中的key删除
            ResultEntity<String> resultEntity = redisRemoteService.removeRedisKeyRemote(register_key);

            // 执行密码加密
            BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
            String userPswd = memberVO.getUserpswd();

            String encode = passwordEncoder.encode(userPswd);
            memberVO.setUserpswd(encode);

            // 复制MemberVO属性给MemberPO
            MemberPO memberPO = new MemberPO();
            BeanUtils.copyProperties(memberVO, memberPO);

            // 执行保存
            ResultEntity<String> entity = mySQLRemoteService.saveMember(memberPO);

            if (ResultEntity.FAILED.equals(entity.getResult())) {
                modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, entity.getMessage());
                return "member-reg";
            }

            // 3、注册成功，前往登录界面
            return "redirect:http://localhost/auth/welcome/member-login";
        } else {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_CODE_FAILED);
            return "member-reg";
        }
    }

    @PostMapping("/auth/welcome/member/login")
    public String doLogin(@RequestParam("loginAcct") String loginAcct, @RequestParam("userPswd") String userPswd, ModelMap modelMap, HttpSession session) {
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        ResultEntity<MemberPO> resultEntity = mySQLRemoteService.getMemberPOByLoginAcctRemote(loginAcct);

        MemberPO memberPO = resultEntity.getData();
        // 获取mysql中用户的密码
        String mysqlPswd = memberPO.getUserpswd();

        // 判断密码是否相等
        boolean matches = passwordEncoder.matches(userPswd, mysqlPswd);
        if (matches) {
            MemberLoginVO memberLoginVO = new MemberLoginVO(memberPO.getId(), memberPO.getUsername(), mysqlPswd);
            session.setAttribute(CrowdConstant.ATTR_SESSION_MESSAGE, memberLoginVO);
            return "redirect:http://localhost/auth/login/success";
        }
        modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, "账号密码错误");
        return "redirect:http://localhost/auth/welcome/member-login";
    }

    @GetMapping("/auth/login/member/logout")
    public String doLogOut(HttpSession session) {
        session.removeAttribute(CrowdConstant.ATTR_SESSION_MESSAGE);
        return "redirect:http://localhost";
    }

    /**
     * 展示商品详情
     * @return 主页视图
     */
    @RequestMapping("/")
    public String showGoodsDetail(Model model){
        // 1.调用MySQLRemoteService提供的方法查询首页要显示的数据
        ResultEntity<List<PortalTypeVO>> projectDataRemote = mySQLRemoteService.getPortalTypeProjectDataRemote();

        // 2.检查查询结果
        String result = projectDataRemote.getResult();
        if (ResultEntity.SUCCESS.equals(result)) {
            // 3.获取查询结果数据
            List<PortalTypeVO> typeVOList = projectDataRemote.getData();

            log.info("List<PortalTypeVO> : {}", typeVOList);

            // 4.存入数据
            model.addAttribute(CrowdConstant.ATTR_NAME_PORTAL_DATA, typeVOList);
        }

        return "portal";
    }

    @GetMapping("/project/test/auth")
    @ResponseBody
    public String testAuth(){
        return "AUTH_PROJECT";
    }
}
